// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package base

import (
	"sync/atomic"
)

const (
	TracingOnContext = "__SpanContext__"
)

// Tracing
// is a component of a trace.
type Tracing struct {
	ParentSpanId       *SpanId
	ParentSpanPosition int32
	SpanId             *SpanId
	SpanPosition       int32
	TraceId            *TraceId
}

// NewTracing
// creates a new tracing.
func NewTracing() *Tracing {
	o := &Tracing{}
	o.TraceId = NewTraceId()
	o.SpanId = NewSpanId()
	return o
}

// NewTracingWithHex
// creates a new tracing with hex string.
func NewTracingWithHex(tid, sid string, position int32) *Tracing {
	o := &Tracing{}
	o.TraceId = NewTraceIdWithHex(tid)
	o.ParentSpanId = NewSpanIdWithHex(sid)
	o.ParentSpanPosition = position
	o.SpanId = NewSpanId()
	return o
}

// Child
// creates a child tracing.
func (o *Tracing) Child() *Tracing {
	c := &Tracing{TraceId: o.TraceId, ParentSpanPosition: o.SpanPosition, ParentSpanId: o.SpanId}
	c.SpanId = NewSpanId()
	return c
}

// Increment
// increments the span position.
func (o *Tracing) Increment() (before, after int32) {
	after = atomic.AddInt32(&o.SpanPosition, 1)
	before = after - 1
	return
}
